package demo18

// visitor  访问者设计模式
import "fmt"

// 顾客
type Customer interface{
	Accept(Visitor) // 是否接受邀请
}
// 访问者 
type Visitor interface {
	Visit(Customer) // 邀请客户
}

// 公司客户
type EnterpriseCustomer struct{
	name string  
}

type CustomerCol struct{
	customers []Customer // 客户群体
}

func (c *CustomerCol) Add(customer Customer){
	c.customers = append(c.customers,customer)
}

// 集体接受邀请
func (c *CustomerCol)Accept(visitor Visitor){
	for _, customer := range c.customers{
		customer.Accept(visitor)
	}
}

func NewEnterpriseCustomer(name string) *EnterpriseCustomer{
	return &EnterpriseCustomer{
		name:name,
	}
}

// 邀请公司的客户 接受邀请
func (c *EnterpriseCustomer)Accept(visitor Visitor){
	visitor.Visit(c)
}

type IndividualCustomer struct{
	name string
}
func NewIndividualCustomer(name string) *IndividualCustomer{
	return &IndividualCustomer{
		name:name,
	}
}
func(c *IndividualCustomer)Accept(visitor Visitor){
	visitor.Visit(c)
}

type ServiceRequestVisitor struct{}

func (*ServiceRequestVisitor)Visit(customer Customer){
	switch c := customer.(type) {
	case *EnterpriseCustomer:
		fmt.Printf("serving enterprise customer %s\n",c.name)
	case *IndividualCustomer:
		fmt.Printf("serving individual customer %s\n",c.name)
	}
}

// only for enterprise

type AnalysisVistor struct{}
func (*AnalysisVistor)Visit(customer Customer){
	switch c := customer.(type) {
	case *EnterpriseCustomer:
		fmt.Printf("analysis enterprise customer %s\n",c.name)
	}
}